#

| Chapter 16 Where Did I Put That? |

## 16.6 clf, cls: "Compressed" ls Listings

Most newer UNIX systems let you make filenames that are hundreds of characters long. The bad thing about that is that when ls lists the filenames in columns, it can't fit many columns across the screen. If your directory has a lot of files, the listing can scroll off the screen.

I wrote a script that lists a directory in five columns. If a filename doesn't fit, the script truncates the name and prints a right angle bracket (`>`) at the end of the name. Here's a demo. It starts with the standard ls and its -F option (16.12) to mark directories with a trailing `/` and executable files with a `*`. Next, clf gives the same listing, compressed. Third, cls gives a listing without the `/` and `*`.

>     % ls -F
>     HOMEDIR_backup/                         more*
>     adir/                                   projects.1995/
>     afile                                   projects.1996/
>     cfile                                   updatedb.client
>     dfile                                   zfile
>     file_with_a_very_long_name_what_a_mess* zoo.tar.Z
>     jerryp_MH.tar.Z

>     % clf
>     HOMEDIR_back>/ cfile          jerryp_MH.tar> projects.1996/ zoo.tar.Z
>     adir/          dfile          more*          updatedb.clie>
>     afile          file_with_a_>* projects.1995/ zfile
>     % cls
>     HOMEDIR_backup cfile          jerryp_MH.tar> projects.1996  zoo.tar.Z
>     adir           dfile          more           updatedb.clie>
>     afile          file_with_a_v> projects.1995  zfile

cls | The script has a total of four names (links). cls lists in columns that are sorted top to bottom. clf is like cls, but marks directories and executable files. cls2 and clf2 are like cls and clf, but they sort filenames side to side instead; this is faster but may not be as easy to read. The script tests its name and does the right commands in a case statement (44.6) that starts like this:

>     case "$0" in
>     *clf2)  $ls -F ${1+"$@"} | sed -e "$sed" | $pr -l1; exit ;;
>        ...

The `${1+"$@"}` passes in quoted filenames from the command line without breaking them into pieces at the spaces. This is a workaround for differences in the way some old Bourne shellshandle an empty `"$@"` parameter . (46.7)

The "guts" of the shell script is the two-line sed (34.24) command below (the single quotes around the expression pass both lines into the shell variable at once):

>     sed='/[/@*=]$/s/^\(............\)...*\([/@*=][/@*=]*\)$/\1>\2/
>     s/^\(.............\)...*/\1>/'

The ls output is piped to sed's standard input:

- The first sed script line matches lines that are more than 14 characters long and end with one of the symbols `*`, `/`, `@`, or `=`. The "escaped parenthesis" operators `/(.../)` (34.10) grab the first 12 characters into `\1` and the symbol into `\2`-then print them both together with a `>` between.

- The second sed line matches other filenames over 14 characters that don't end with a symbol. (It won't match filenames that the first line matched because the first line shortened them.) The second line grabs the first 13 characters, prints them with a `>` on the end.

If you figured that out yourself, tell your manager that I think you deserve a promotion `:-)`.

The other tricky part is this line:

    `...`
    $pr -l`expr \( `wc -l < $temp` / 5 \) + 1` $temp

It's used when you call the script clf or cls and the filenames need to be printed down columns instead of across. The same kind of line is used in article 35.16- it's explained there. The time that line takes to run is why clf and cls are a little slower than clf2 and cls2.

You can install this script from the CD-ROM or from the online archive (52.7). If you get it from the archive, ask tar to install cls and its three other links:

>     % tar xvf archive.tar cls clf cls2 clf2
>     x cls, 1282 bytes, 3 tape blocks
>     clf linked to cols
>     cls2 linked to cols
>     clf2 linked to cols

- JP

16.5 The Three UNIX File Times |  | 16.7 ls Shortcuts: ll, lf, lg, etc.